"""
用户列表页面对象类
"""
import logging
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.action_chains import ActionChains
from tests.page_objects.base_page import BasePage


class UserListPage(BasePage):
    """用户列表页面的页面对象模型"""
    
    # 页面URL
    USER_LIST_PAGE_URL = "back/user/list"
    
    # 导航菜单元素 - 使用更精确的XPath定位器
    USER_MENU_ITEM = (By.XPATH, "//li[contains(@class, 'el-sub-menu')]//span[text()='用户管理']/parent::div")
    USER_LIST_MENU_ITEM = (By.XPATH, "//li[contains(@class, 'el-sub-menu') and .//span[text()='用户管理']]//ul/li[contains(text(), '用户列表')]")
    
    # 搜索表单元素 - 使用更稳定的定位器
    USERNAME_INPUT = (By.CSS_SELECTOR, "input[placeholder='请输入用户名']")
    NAME_INPUT = (By.CSS_SELECTOR, "input[placeholder='请输入姓名']")
    ROLE_SELECT = (By.XPATH, "//div[contains(@class, 'el-select__wrapper')]")
    ROLE_FOCUSED = (By.CSS_SELECTOR, ".is-focused")
    SEARCH_BUTTON = (By.XPATH, "//button[.//span[contains(text(), '搜索')]]")
    RESET_BUTTON = (By.XPATH, "//button[.//span[contains(text(), '重置')]]")
    
    # 角色选项 - 使用更稳定的定位器
    ROLE_OPTION_TEMPLATE = "//li[contains(@class, 'el-select-dropdown__item') and contains(text(), '{}')]"
    
    # 表格元素
    TABLE = (By.CSS_SELECTOR, ".el-table")
    TABLE_ROWS = (By.CSS_SELECTOR, ".el-table__row")
    USERNAME_COLUMN = (By.XPATH, "//tr/td[1]")  # 假设用户名是第一列
    NAME_COLUMN = (By.XPATH, "//tr/td[2]")  # 假设姓名是第二列
    
    # 新增用户相关元素定位器 - 使用id属性和更精确的选择器
    ADD_USER_BUTTON = (By.XPATH, "//button[.//span[contains(text(), '新增用户')]]")
    DIALOG_TITLE = (By.CSS_SELECTOR, ".el-dialog__title")
    USERNAME_FORM_INPUT = (By.ID, "username")  # 使用id定位
    NAME_FORM_INPUT = (By.ID, "name")  # 使用id定位
    EMAIL_FORM_INPUT = (By.XPATH, "//label[text()='邮箱']/following-sibling::div//input")
    PHONE_FORM_INPUT = (By.XPATH, "//label[text()='手机号']/following-sibling::div//input")
    SEX_FORM_INPUT = (By.XPATH, "//label[text()='性别']/following-sibling::div//input")
    # 使用多种方式定位角色选择框
    ROLE_FORM_SELECT = (By.ID, "roleCode")  # 使用id定位
    ROLE_FORM_SELECT_PLACEHOLDER = (By.CSS_SELECTOR, "input[placeholder='请选择角色']")  # 使用placeholder定位
    ROLE_FORM_SELECT_LABEL = (By.XPATH, "//label[text()='角色']/following-sibling::div//div[contains(@class, 'el-select')]")  # 使用标签定位
    PASSWORD_FORM_INPUT = (By.XPATH, "//label[text()='密码']/following-sibling::div//input")
    SUBMIT_BUTTON = (By.XPATH, "//span[text()='确定']/parent::button")
    CANCEL_BUTTON = (By.XPATH, "//span[text()='取消']/parent::button")
    
    def __init__(self, driver):
        """
        初始化用户列表页面对象
        
        Args:
            driver: WebDriver实例
        """
        super().__init__(driver)
        self.wait = WebDriverWait(self.driver, 10)
        self.actions = ActionChains(self.driver)
    
    def open_user_list_page(self):
        """
        打开用户列表页面
        """
        logging.info("打开用户列表页面")
        self.open(self.USER_LIST_PAGE_URL)
        return self
    
    def navigate_to_user_list(self):
        """
        通过菜单导航到用户列表页面
        使用更稳定的元素定位策略
        """
        logging.info("通过菜单导航到用户列表页面")
        
        try:
            # 等待页面加载完成
            self.wait_for_page_load()
            
            # 尝试使用绝对XPath定位用户管理菜单
            try:
                logging.info("尝试使用绝对XPath定位用户管理菜单")
                user_menu = self.wait.until(EC.element_to_be_clickable((By.XPATH, "/html/body/div[1]/div/div[1]/div[2]/ul/li[4]/div")))
                logging.info("成功找到用户管理菜单")
            except Exception as e:
                logging.warning(f"使用绝对XPath定位用户管理菜单失败: {e}")
                
                # 尝试使用相对XPath定位
                try:
                    logging.info("尝试使用相对XPath定位用户管理菜单")
                    user_menu = self.wait.until(EC.element_to_be_clickable(self.USER_MENU_ITEM))
                    logging.info("成功找到用户管理菜单")
                except Exception as e:
                    logging.warning(f"使用相对XPath定位用户管理菜单失败: {e}")
                    
                    # 使用JavaScript查找包含"用户管理"文本的菜单
                    logging.info("使用JavaScript查找用户管理菜单")
                    self.driver.execute_script("""
                    var menuItems = document.querySelectorAll('.el-sub-menu__title');
                    for (var i = 0; i < menuItems.length; i++) {
                        if (menuItems[i].textContent.includes('用户管理')) {
                            menuItems[i].click();
                            console.log('已点击用户管理菜单');
                            break;
                        }
                    }
                    """)
                    # time.sleep(2)
                    
                    # 使用JavaScript查找并点击用户列表子菜单
                    logging.info("使用JavaScript查找用户列表子菜单")
                    self.driver.execute_script("""
                    var menuItems = document.querySelectorAll('.el-menu-item');
                    for (var i = 0; i < menuItems.length; i++) {
                        if (menuItems[i].textContent.includes('用户列表')) {
                            menuItems[i].click();
                            console.log('已点击用户列表子菜单');
                            break;
                        }
                    }
                    """)
                    # time.sleep(2)
                    return self
            
            # 点击用户管理菜单
            self.actions.move_to_element(user_menu).perform()
            user_menu.click()
            logging.info("已点击用户管理菜单")
            
            # 等待子菜单展开
            time.sleep(1)
            
            # 尝试使用绝对XPath定位用户列表子菜单
            try:
                logging.info("尝试使用绝对XPath定位用户列表子菜单")
                user_list_menu = self.wait.until(EC.element_to_be_clickable(
                    (By.XPATH, "/html/body/div[1]/div/div[1]/div[2]/ul/li[4]/ul/li[1]")
                ))
                logging.info("成功找到用户列表子菜单")
            except Exception as e:
                logging.warning(f"使用绝对XPath定位用户列表子菜单失败: {e}")
                
                # 尝试使用相对XPath定位
                try:
                    logging.info("尝试使用相对XPath定位用户列表子菜单")
                    user_list_menu = self.wait.until(EC.element_to_be_clickable(self.USER_LIST_MENU_ITEM))
                    logging.info("成功找到用户列表子菜单")
                except Exception as e:
                    logging.warning(f"使用相对XPath定位用户列表子菜单失败: {e}")
                    
                    # 使用JavaScript查找包含"用户列表"文本的菜单项
                    logging.info("使用JavaScript查找用户列表子菜单")
                    self.driver.execute_script("""
                    var menuItems = document.querySelectorAll('.el-menu-item');
                    for (var i = 0; i < menuItems.length; i++) {
                        if (menuItems[i].textContent.includes('用户列表')) {
                            menuItems[i].click();
                            console.log('已点击用户列表子菜单');
                            break;
                        }
                    }
                    """)
                    # time.sleep(2)
                    return self
            
            # 点击用户列表子菜单
            user_list_menu.click()
            logging.info("已点击用户列表子菜单")
            
            # 等待页面加载
            time.sleep(2)
            
            return self
        except Exception as e:
            logging.warning(f"通过菜单导航失败: {e}")
            # 如果导航失败，直接打开页面
            return self.open_user_list_page()
    
    def enter_username(self, username):
        """
        输入用户名进行搜索
        
        Args:
            username: 要搜索的用户名
        """
        logging.info(f"输入用户名: {username}")
        
        try:
            # 使用placeholder属性定位输入框
            username_input = self.wait.until(
                EC.element_to_be_clickable(self.USERNAME_INPUT)
            )
            username_input.clear()
            username_input.send_keys(username)
            logging.info(f"已输入用户名: {username}")
        except Exception as e:
            logging.warning(f"使用CSS选择器定位用户名输入框失败: {e}")
            # 尝试使用JavaScript定位和填充
            self.driver.execute_script(f"""
            var inputs = document.querySelectorAll('input');
            for (var i = 0; i < inputs.length; i++) {{
                if (inputs[i].placeholder === '请输入用户名') {{
                    inputs[i].value = '{username}';
                    var event = new Event('input', {{ bubbles: true }});
                    inputs[i].dispatchEvent(event);
                    break;
                }}
            }}
            """)
            logging.info(f"已使用JavaScript输入用户名: {username}")
        
        return self
    
    def enter_name(self, name):
        """
        输入姓名进行搜索
        
        Args:
            name: 要搜索的姓名
        """
        logging.info(f"输入姓名: {name}")
        
        try:
            # 使用placeholder属性定位输入框
            name_input = self.wait.until(
                EC.element_to_be_clickable(self.NAME_INPUT)
            )
            name_input.clear()
            name_input.send_keys(name)
            logging.info(f"已输入姓名: {name}")
        except Exception as e:
            logging.warning(f"使用CSS选择器定位姓名输入框失败: {e}")
            # 尝试使用JavaScript定位和填充
            self.driver.execute_script(f"""
            var inputs = document.querySelectorAll('input');
            for (var i = 0; i < inputs.length; i++) {{
                if (inputs[i].placeholder === '请输入姓名') {{
                    inputs[i].value = '{name}';
                    var event = new Event('input', {{ bubbles: true }});
                    inputs[i].dispatchEvent(event);
                    break;
                }}
            }}
            """)
            logging.info(f"已使用JavaScript输入姓名: {name}")
        
        return self
    
    def select_role(self, role_name):
        """
        选择角色进行搜索
        
        Args:
            role_name: 要选择的角色名称
        """
        logging.info(f"选择角色: {role_name}")
        
        try:
            # 点击角色下拉框
            role_select = self.wait.until(EC.element_to_be_clickable(self.ROLE_SELECT))
            role_select.click()
            logging.info("已点击角色下拉框")
            
            # 等待下拉选项显示
            time.sleep(1)
            
            # 使用角色名称定位选项
            role_option_locator = (By.XPATH, self.ROLE_OPTION_TEMPLATE.format(role_name))
            role_option = self.wait.until(EC.element_to_be_clickable(role_option_locator))
            role_option.click()
            logging.info(f"已选择角色: {role_name}")
        except Exception as e:
            logging.warning(f"使用常规方法选择角色失败: {e}")
            # 尝试使用JavaScript选择角色
            self.driver.execute_script(f"""
            // 点击下拉框
            var selects = document.querySelectorAll('.el-select__wrapper');
            if (selects.length > 0) {{
                selects[0].click();
                
                // 等待选项显示
                setTimeout(function() {{
                    // 查找并点击包含指定文本的选项
                    var options = document.querySelectorAll('.el-select-dropdown__item');
                    for (var i = 0; i < options.length; i++) {{
                        if (options[i].textContent.includes('{role_name}')) {{
                            options[i].click();
                            break;
                        }}
                    }}
                }}, 500);
            }}
            """)
            logging.info(f"已使用JavaScript选择角色: {role_name}")
            time.sleep(1)  # 等待JavaScript执行完成
        
        return self
    
    def click_search(self):
        """
        点击搜索按钮
        """
        logging.info("点击搜索按钮")
        
        try:
            # 使用XPath定位搜索按钮
            search_button = self.wait.until(EC.element_to_be_clickable(self.SEARCH_BUTTON))
            search_button.click()
            logging.info("已点击搜索按钮")
        except Exception as e:
            logging.warning(f"使用XPath定位搜索按钮失败: {e}")
            # 尝试使用JavaScript点击
            self.driver.execute_script("""
            var buttons = document.querySelectorAll('button');
            for (var i = 0; i < buttons.length; i++) {
                if (buttons[i].textContent.includes('搜索')) {
                    buttons[i].click();
                    break;
                }
            }
            """)
            logging.info("已使用JavaScript点击搜索按钮")
        
        # 等待搜索结果加载
        # time.sleep(2)
        return self
    
    def click_reset(self):
        """
        点击重置按钮
        """
        logging.info("点击重置按钮")
        
        try:
            # 使用XPath定位重置按钮
            reset_button = self.wait.until(EC.element_to_be_clickable(self.RESET_BUTTON))
            reset_button.click()
            logging.info("已点击重置按钮")
        except Exception as e:
            logging.warning(f"使用XPath定位重置按钮失败: {e}")
            # 尝试使用JavaScript点击
            self.driver.execute_script("""
            var buttons = document.querySelectorAll('button');
            for (var i = 0; i < buttons.length; i++) {
                if (buttons[i].textContent.includes('重置')) {
                    buttons[i].click();
                    break;
                }
            }
            """)
            logging.info("已使用JavaScript点击重置按钮")
        
        return self
    
    def search_user(self, username="", name="", role=""):
        """
        搜索用户
        
        Args:
            username: 用户名，默认为空
            name: 姓名，默认为空
            role: 角色，默认为空
        """
        logging.info(f"搜索用户: 用户名={username}, 姓名={name}, 角色={role}")
        
        # 输入搜索条件
        if username:
            self.enter_username(username)
        
        if name:
            self.enter_name(name)
        
        if role:
            self.select_role(role)
        
        # 点击搜索按钮
        return self.click_search()
    
    def get_search_results(self):
        """
        获取搜索结果
        
        Returns:
            搜索结果列表，每个元素是一个包含用户信息的字典
        """
        logging.info("获取搜索结果")
        
        try:
            # 等待表格加载
            self.wait.until(EC.presence_of_element_located(self.TABLE))
            
            # 使用JavaScript获取表格数据，更可靠
            table_data = self.driver.execute_script("""
            var results = [];
            var rows = document.querySelectorAll('.el-table__row');
            
            console.log('找到 ' + rows.length + ' 行数据');
            
            for (var i = 0; i < rows.length; i++) {
                var cells = rows[i].querySelectorAll('td');
                if (cells.length >= 2) {
                    var username = cells[0].textContent.trim();
                    var name = cells[1].textContent.trim();
                    var role = cells.length > 2 ? cells[2].textContent.trim() : "";
                    
                    console.log('行 ' + i + ': 用户名=' + username + ', 姓名=' + name + ', 角色=' + role);
                    
                    results.push({
                        username: username,
                        name: name,
                        role: role
                    });
                }
            }
            
            return results;
            """)
            
            logging.info(f"JavaScript获取到 {len(table_data)} 条搜索结果")
            
            # 记录每条结果的详细信息
            for i, user in enumerate(table_data):
                logging.info(f"结果 {i+1}: 用户名={user.get('username', '')}, 姓名={user.get('name', '')}, 角色={user.get('role', '')}")
            
            return table_data
        except Exception as e:
            logging.error(f"获取搜索结果失败: {e}")
            self.take_screenshot("search_results_error")
            
            # 尝试使用备用方法获取表格数据
            try:
                logging.info("使用备用方法获取表格数据")
                rows = self.find_elements(self.TABLE_ROWS)
                
                if not rows:
                    logging.info("搜索结果为空")
                    return []
                
                results = []
                for row in rows:
                    # 获取每行的单元格
                    cells = row.find_elements(By.TAG_NAME, "td")
                    
                    if len(cells) >= 2:  # 确保至少有用户名、姓名两列
                        user_info = {
                            "username": cells[0].text.strip(),
                            "name": cells[1].text.strip(),
                            "role": cells[2].text.strip() if len(cells) > 2 else ""
                        }
                        results.append(user_info)
                        logging.info(f"找到用户: {user_info['username']}, {user_info['name']}")
                
                logging.info(f"备用方法找到 {len(results)} 条搜索结果")
                return results
            except Exception as e2:
                logging.error(f"备用方法获取搜索结果也失败: {e2}")
                return []
    
    def is_user_in_results(self, username, name):
        """
        检查指定用户是否在搜索结果中
        
        Args:
            username: 要检查的用户名
            name: 要检查的姓名
            
        Returns:
            布尔值，表示用户是否在结果中
        """
        results = self.get_search_results()
        
        logging.info(f"检查用户 {username}, {name} 是否在搜索结果中")
        logging.info(f"搜索结果数量: {len(results)}")
        
        # 记录所有结果，便于调试
        for i, user in enumerate(results):
            logging.info(f"结果 {i+1}: 用户名={user.get('username', '')}, 姓名={user.get('name', '')}")
        
        # 使用模糊匹配，更宽松的比较
        for user in results:
            user_username = user.get('username', '').strip()
            user_name = user.get('name', '').strip()
            
            logging.info(f"比较: '{user_username}' vs '{username}', '{user_name}' vs '{name}'")
            
            if (username.lower() in user_username.lower() and 
                name.lower() in user_name.lower()):
                logging.info(f"在搜索结果中找到匹配的用户: {user_username}, {user_name}")
                return True
        
        logging.warning(f"在搜索结果中未找到用户: {username}, {name}")
        return False
        
    def click_add_user_button(self):
        """
        点击新增用户按钮
        """
        logging.info("点击新增用户按钮")
        
        try:
            # 使用XPath定位新增用户按钮
            add_button = self.wait.until(EC.element_to_be_clickable(self.ADD_USER_BUTTON))
            add_button.click()
            logging.info("已点击新增用户按钮")
        except Exception as e:
            logging.warning(f"使用XPath定位新增用户按钮失败: {e}")
            # 尝试使用JavaScript点击
            self.driver.execute_script("""
            var buttons = document.querySelectorAll('button');
            for (var i = 0; i < buttons.length; i++) {
                if (buttons[i].textContent.includes('新增用户')) {
                    buttons[i].click();
                    console.log('已点击新增用户按钮');
                    break;
                }
            }
            """)
            logging.info("已使用JavaScript点击新增用户按钮")
        
        # 等待对话框显示
        time.sleep(1)
        
        # 验证对话框标题
        try:
            dialog_title = self.wait.until(EC.presence_of_element_located(self.DIALOG_TITLE))
            if "新增用户" in dialog_title.text:
                logging.info("新增用户对话框已打开")
            else:
                logging.warning(f"对话框标题不是'新增用户'，而是: {dialog_title.text}")
        except Exception as e:
            logging.warning(f"无法验证对话框标题: {e}")
            # 截图记录当前状态
            self.take_screenshot("add_user_dialog_opened")
        
        return self
    
    def fill_user_form(self, username, name, email, phone="", sex="", role_code="", password="123456"):
        """
        填写用户表单
        
        Args:
            username: 用户名
            name: 姓名
            email: 邮箱
            phone: 手机号，可选
            sex: 性别，可选
            role_code: 角色代码，可选
            password: 密码，默认为123456
        """
        logging.info(f"填写用户表单: 用户名={username}, 姓名={name}, 邮箱={email}")
        
        try:
            # 填写用户名
            self._fill_input_field(self.USERNAME_FORM_INPUT, username, "用户名")
            
            # 填写姓名
            self._fill_input_field(self.NAME_FORM_INPUT, name, "姓名")
            
            # 填写邮箱
            self._fill_input_field(self.EMAIL_FORM_INPUT, email, "邮箱")
            
            # 填写手机号（如果提供）
            if phone:
                self._fill_input_field(self.PHONE_FORM_INPUT, phone, "手机号")
            
            # 填写性别（如果提供）
            if sex:
                self._fill_input_field(self.SEX_FORM_INPUT, sex, "性别")
            
            # 选择角色（如果提供）
            if role_code:
                self._select_role_in_form(role_code)
            
            # 填写密码
            self._fill_input_field(self.PASSWORD_FORM_INPUT, password, "密码")
            
            logging.info("用户表单填写完成")
        except Exception as e:
            logging.error(f"填写用户表单失败: {e}")
            # 截图记录当前状态
            self.take_screenshot("fill_user_form_failed")
            
            # 尝试使用JavaScript填写表单
            self._fill_user_form_with_js(username, name, email, phone, sex, role_code, password)
        
        return self
    
    def _fill_input_field(self, locator, value, field_name):
        """
        填写输入框
        
        Args:
            locator: 元素定位器
            value: 要输入的值
            field_name: 字段名称，用于日志记录
        """
        try:
            input_field = self.wait.until(EC.element_to_be_clickable(locator))
            input_field.clear()
            input_field.send_keys(value)
            logging.info(f"已填写{field_name}: {value}")
        except Exception as e:
            logging.warning(f"填写{field_name}失败: {e}")
            raise
    
    def _select_role_in_form(self, role_code):
        """
        在表单中选择角色
        
        Args:
            role_code: 角色代码
        """
        logging.info(f"选择角色: {role_code}")
        
        # 调用无参数版本的方法
        return self.select_role_in_form()
    
    def select_role_in_form(self):
        """
        在表单中选择角色
        """
        logging.info("选择角色")
        
        # 截图记录选择前状态
        self.take_screenshot("before_select_role")
        
        try:
            # 使用更可靠的JavaScript方法处理Element Plus下拉框
            # 注意：这里专门针对新增用户对话框中的角色下拉框，而不是搜索表单中的
            self.driver.execute_script("""
            try {
                console.log("开始处理新增用户对话框中的角色选择...");
                
                // 1. 首先确认我们在对话框中
                var dialog = document.querySelector('.el-dialog');
                if (!dialog) {
                    throw new Error("未找到对话框");
                }
                
                console.log("找到对话框");
                
                // 2. 在对话框中查找角色表单项
                var roleFormItem = dialog.querySelector('.el-form-item[prop="roleCode"]');
                if (!roleFormItem) {
                    // 备用方法：通过标签文本查找
                    var labels = dialog.querySelectorAll('label');
                    for (var i = 0; i < labels.length; i++) {
                        if (labels[i].textContent.includes('角色')) {
                            roleFormItem = labels[i].closest('.el-form-item');
                            break;
                        }
                    }
                }
                
                if (!roleFormItem) {
                    throw new Error("在对话框中未找到角色表单项");
                }
                
                console.log("在对话框中找到角色表单项");
                
                // 3. 查找角色下拉框
                var roleSelect = roleFormItem.querySelector('.el-select');
                if (!roleSelect) {
                    throw new Error("未找到角色下拉框");
                }
                
                console.log("找到角色下拉框");
                
                // 4. 查找并点击输入框以显示下拉菜单
                var selectInput = roleSelect.querySelector('input');
                if (!selectInput) {
                    throw new Error("未找到角色下拉框输入框");
                }
                
                console.log("找到角色下拉框输入框，点击显示下拉菜单");
                
                // 使用事件模拟点击，更可靠
                selectInput.click();
                console.log("已点击角色下拉框输入框");
                
                // 使用多种事件触发方式确保下拉框打开
                var clickEvent = new MouseEvent('mousedown', {
                    bubbles: true,
                    cancelable: true,
                    view: window
                });
                selectInput.dispatchEvent(clickEvent);
                console.log("已触发mousedown事件");
                
                // 5. 等待下拉菜单显示，然后选择第一个选项
                console.log("等待下拉菜单显示...");
                
                setTimeout(function() {
                    // 查找所有下拉菜单
                    var dropdowns = document.querySelectorAll('.el-select-dropdown');
                    console.log("找到下拉菜单数量: " + dropdowns.length);
                    
                    // 找到可见的下拉菜单
                    var visibleDropdown = Array.from(dropdowns).find(function(el) {
                        var style = window.getComputedStyle(el);
                        return style.display !== 'none' && el.offsetHeight > 0;
                    });
                    
                    if (!visibleDropdown) {
                        console.log("未找到可见的下拉菜单，尝试直接设置值");
                        
                        // 尝试直接设置值 - 这是针对Element Plus组件的特殊处理
                        // 1. 尝试通过Vue实例设置值
                        try {
                            // 获取Vue实例
                            var formComponent = dialog.__vue__.$children.find(c => c.$options._componentTag === 'el-form');
                            if (formComponent && formComponent.model) {
                                formComponent.model.roleCode = 'admin';
                                console.log("已通过Vue实例设置roleCode = admin");
                            }
                        } catch (e) {
                            console.log("通过Vue实例设置值失败: " + e);
                        }
                        
                        // 2. 尝试设置隐藏输入值
                        var hiddenInput = roleSelect.querySelector('input[type="hidden"]');
                        if (hiddenInput) {
                            hiddenInput.value = "admin";
                            hiddenInput.dispatchEvent(new Event('input', { bubbles: true }));
                            hiddenInput.dispatchEvent(new Event('change', { bubbles: true }));
                            console.log("已设置隐藏输入值为admin");
                        }
                        
                        // 3. 设置显示值
                        if (selectInput) {
                            selectInput.value = "系统管理员";
                            selectInput.dispatchEvent(new Event('input', { bubbles: true }));
                            console.log("已设置显示值为系统管理员");
                        }
                        
                        return;
                    }
                    
                    console.log("找到可见下拉菜单");
                    
                    // 查找下拉选项
                    var options = visibleDropdown.querySelectorAll('.el-select-dropdown__item');
                    console.log("找到选项数量: " + options.length);
                    
                    if (options.length > 0) {
                        // 点击第一个选项
                        console.log("点击第一个选项: " + options[0].textContent);
                        options[0].click();
                        
                        // 使用事件确保点击被正确处理
                        var optionClickEvent = new MouseEvent('click', {
                            bubbles: true,
                            cancelable: true,
                            view: window
                        });
                        options[0].dispatchEvent(optionClickEvent);
                        console.log("已点击第一个选项");
                    } else {
                        console.log("未找到下拉选项");
                        
                        // 如果没有选项，尝试直接设置值
                        if (selectInput) {
                            selectInput.value = "系统管理员";
                            selectInput.dispatchEvent(new Event('input', { bubbles: true }));
                            console.log("已设置显示值为系统管理员");
                            
                            // 模拟关闭下拉菜单
                            document.body.click();
                        }
                    }
                }, 1000);
            } catch(e) {
                console.error("选择角色时出错: " + e.message);
                
                // 备用方案：直接在对话框中设置表单数据
                console.log("使用备用方案设置角色值");
                
                try {
                    // 查找对话框
                    var dialog = document.querySelector('.el-dialog');
                    if (dialog) {
                        // 尝试通过Vue实例设置值
                        try {
                            // 获取Vue实例
                            var vm = dialog.__vue__;
                            if (vm && vm.form) {
                                vm.form.roleCode = 'admin';
                                console.log("已通过Vue实例设置roleCode = admin");
                            }
                        } catch (e) {
                            console.log("通过Vue实例设置值失败: " + e);
                        }
                        
                        // 尝试直接在表单模型中设置值
                        var formItems = dialog.querySelectorAll('.el-form-item');
                        for (var i = 0; i < formItems.length; i++) {
                            if (formItems[i].textContent.includes('角色')) {
                                // 查找下拉框
                                var select = formItems[i].querySelector('.el-select');
                                if (select) {
                                    // 设置隐藏输入值
                                    var hiddenInput = select.querySelector('input[type="hidden"]');
                                    if (hiddenInput) {
                                        hiddenInput.value = "admin";
                                        hiddenInput.dispatchEvent(new Event('input', { bubbles: true }));
                                        hiddenInput.dispatchEvent(new Event('change', { bubbles: true }));
                                        console.log("已设置隐藏输入值为admin");
                                    }
                                    
                                    // 设置显示输入值
                                    var visibleInput = select.querySelector('input:not([type="hidden"])');
                                    if (visibleInput) {
                                        visibleInput.value = "系统管理员";
                                        visibleInput.dispatchEvent(new Event('input', { bubbles: true }));
                                        console.log("已设置显示输入值为系统管理员");
                                    }
                                }
                            }
                        }
                    }
                } catch(e2) {
                    console.error("备用方案设置角色值失败: " + e2.message);
                }
            }
            """)
            
            # 等待JavaScript执行完成
            time.sleep(3)
            
            logging.info("已执行角色选择JavaScript")
            
        except Exception as e:
            logging.error(f"选择角色失败: {e}")
            self.take_screenshot("select_role_failed")
            # 不抛出异常，继续执行
        
        # 截图记录选择后状态
        self.take_screenshot("after_select_role")
        return self
    
    def _fill_user_form_with_js(self, username, name, email, phone, sex, role_code, password):
        """
        使用JavaScript填写用户表单
        
        Args:
            username: 用户名
            name: 姓名
            email: 邮箱
            phone: 手机号
            sex: 性别
            role_code: 角色代码
            password: 密码
        """
        logging.info("使用JavaScript填写用户表单")
        
        # 首先截图记录表单初始状态
        self.take_screenshot("before_fill_form")
        
        # 使用id属性填写用户名和姓名
        self.driver.execute_script(f"""
        try {{
            console.log("使用id属性填写用户名和姓名...");
            
            // 填写用户名 - 使用id属性
            var usernameInput = document.getElementById("username");
            if (usernameInput) {{
                usernameInput.value = "{username}";
                usernameInput.dispatchEvent(new Event('input', {{ bubbles: true }}));
                console.log("已填写用户名: " + usernameInput.value);
            }} else {{
                console.log("未找到用户名输入框 (id=username)");
            }}
            
            // 填写姓名 - 使用id属性
            var nameInput = document.getElementById("name");
            if (nameInput) {{
                nameInput.value = "{name}";
                nameInput.dispatchEvent(new Event('input', {{ bubbles: true }}));
                console.log("已填写姓名: " + nameInput.value);
            }} else {{
                console.log("未找到姓名输入框 (id=name)");
            }}
            
            // 填写邮箱
            var emailInput = document.evaluate("//label[text()='邮箱']/following-sibling::div//input", 
                                            document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
            if (emailInput) {{
                emailInput.value = "{email}";
                emailInput.dispatchEvent(new Event('input', {{ bubbles: true }}));
                console.log("已填写邮箱: " + emailInput.value);
            }} else {{
                console.log("未找到邮箱输入框");
            }}
            
            // 填写手机号
            if ("{phone}") {{
                var phoneInput = document.evaluate("//label[text()='手机号']/following-sibling::div//input", 
                                               document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
                if (phoneInput) {{
                    phoneInput.value = "{phone}";
                    phoneInput.dispatchEvent(new Event('input', {{ bubbles: true }}));
                    console.log("已填写手机号: " + phoneInput.value);
                }} else {{
                    console.log("未找到手机号输入框");
                }}
            }}
            
            // 填写性别
            if ("{sex}") {{
                var sexInput = document.evaluate("//label[text()='性别']/following-sibling::div//input", 
                                             document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
                if (sexInput) {{
                    sexInput.value = "{sex}";
                    sexInput.dispatchEvent(new Event('input', {{ bubbles: true }}));
                    console.log("已填写性别: " + sexInput.value);
                }} else {{
                    console.log("未找到性别输入框");
                }}
            }}
        }} catch(e) {{
            console.log("填写表单基本信息时出错: " + e);
        }}
        """)
        
        # 等待基本信息填写完成
        time.sleep(1)
        
        # 截图记录基本信息填写状态
        self.take_screenshot("after_basic_info_filled")
        
        # 填写密码
        self.driver.execute_script(f"""
        try {{
            console.log("开始填写密码...");
            
            // 查找密码输入框
            var passwordInput = document.querySelector('input[type="password"]');
            if (passwordInput) {{
                passwordInput.value = "{password}";
                passwordInput.dispatchEvent(new Event('input', {{ bubbles: true }}));
                console.log("已填写密码: " + passwordInput.value.replace(/./g, '*'));
            }} else {{
                console.log("未找到密码输入框");
            }}
        }} catch(e) {{
            console.log("填写密码时出错: " + e);
        }}
        """)
        
        # 截图记录表单填写后的状态
        self.take_screenshot("after_fill_form")
        
        logging.info("已使用JavaScript填写用户表单")
        
        # 不在这里处理角色选择，而是在add_new_user方法中单独调用select_role_in_form
        
        return self
    
    def submit_user_form(self):
        """
        提交用户表单
        """
        logging.info("提交用户表单")
        
        try:
            # 截图记录提交前的状态
            self.take_screenshot("before_submit_form")
            
            # 尝试使用XPath定位确定按钮
            try:
                submit_button = self.wait.until(EC.element_to_be_clickable(self.SUBMIT_BUTTON))
                submit_button.click()
                logging.info("已点击确定按钮")
            except Exception as e:
                logging.warning(f"使用XPath定位确定按钮失败: {e}")
                # 尝试使用JavaScript点击
                self.driver.execute_script("""
                try {
                    console.log("开始查找确定按钮...");
                    
                    // 查找所有按钮
                    var buttons = document.querySelectorAll('button');
                    console.log("找到 " + buttons.length + " 个按钮");
                    
                    // 查找确定按钮并点击
                    var submitButton = null;
                    for (var i = 0; i < buttons.length; i++) {
                        if (buttons[i].textContent.includes('确定')) {
                            submitButton = buttons[i];
                            break;
                        }
                    }
                    
                    if (submitButton) {
                        console.log("找到确定按钮，点击中...");
                        // 使用JS事件触发点击，避免被拦截
                        var clickEvent = new MouseEvent('click', {
                            bubbles: true,
                            cancelable: true,
                            view: window
                        });
                        submitButton.dispatchEvent(clickEvent);
                        console.log('已点击确定按钮');
                    } else {
                        console.log('未找到确定按钮');
                    }
                } catch(e) {
                    console.log("点击确定按钮时出错: " + e);
                }
                """)
                logging.info("已使用JavaScript点击确定按钮")
            
            # 等待对话框关闭
            time.sleep(2)
            
            # 截图记录提交后的状态
            self.take_screenshot("user_form_submitted")
            
        except Exception as e:
            logging.error(f"提交表单失败: {e}")
            self.take_screenshot("submit_form_failed")
            raise
        
        return self
    
    def cancel_user_form(self):
        """
        取消用户表单
        """
        logging.info("取消用户表单")
        
        try:
            # 点击取消按钮
            cancel_button = self.wait.until(EC.element_to_be_clickable(self.CANCEL_BUTTON))
            cancel_button.click()
            logging.info("已点击取消按钮")
        except Exception as e:
            logging.warning(f"使用XPath定位取消按钮失败: {e}")
            # 尝试使用JavaScript点击
            self.driver.execute_script("""
            var buttons = document.querySelectorAll('button');
            for (var i = 0; i < buttons.length; i++) {
                if (buttons[i].textContent.includes('取消')) {
                    buttons[i].click();
                    console.log('已点击取消按钮');
                    break;
                }
            }
            """)
            logging.info("已使用JavaScript点击取消按钮")
        
        # 等待对话框关闭
        time.sleep(1)
        
        return self
    
    def add_new_user(self, username, name, email, phone="", sex="", role_code="", password="123456"):
        """
        添加新用户
        
        Args:
            username: 用户名
            name: 姓名
            email: 邮箱
            phone: 手机号，可选
            sex: 性别，可选
            role_code: 角色代码，可选
            password: 密码，默认为123456
        """
        logging.info(f"添加新用户: 用户名={username}, 姓名={name}, 邮箱={email}")
        
        try:
            # 点击新增用户按钮
            self.click_add_user_button()
            
            # 等待对话框显示 - 增加等待时间确保对话框完全加载
            time.sleep(2)
            
            # 填写基本表单信息
            self.fill_user_form(username, name, email, phone, sex, role_code, password)
            
            # 等待表单填写完成
            time.sleep(1)
            
            # 专门处理角色选择 - 这是关键步骤
            self.select_role_in_form()
            
            # 等待角色选择完成
            time.sleep(2)
            
            # 截图记录提交前状态
            self.take_screenshot("before_submit")
            
            # 提交表单
            self.submit_user_form()
            
            # 等待表格刷新
            time.sleep(3)
            
            # 验证用户是否添加成功
            if self.is_user_in_results(username, name):
                logging.info(f"新用户 {username} 添加成功")
            else:
                logging.warning(f"未在表格中找到新添加的用户 {username}")
            
        except Exception as e:
            logging.error(f"添加新用户失败: {e}")
            # 截图记录失败状态
            self.take_screenshot("add_user_failed")
            raise
        
        return self
    
    def click_edit_button_for_user(self, username):
        """
        点击指定用户的编辑按钮
        
        Args:
            username: 要编辑的用户名
        """
        logging.info(f"点击用户 {username} 的编辑按钮")
        
        try:
            # 先搜索用户
            self.search_user(username=username)
            time.sleep(2)
            
            # 方法1: 使用XPath直接定位编辑按钮
            try:
                logging.info("尝试使用XPath直接定位编辑按钮")
                # 定位包含用户名的行
                row_xpath = f"//td[contains(text(), '{username}')]/ancestor::tr"
                # 在该行中定位编辑按钮
                edit_button_xpath = f"{row_xpath}//button[contains(@class, 'el-button--primary') and contains(@class, 'is-link')]//span[text()='编辑']/parent::button"
                
                edit_button = self.wait.until(EC.element_to_be_clickable((By.XPATH, edit_button_xpath)))
                logging.info("找到编辑按钮，点击中...")
                
                # 使用ActionChains点击按钮
                self.actions.move_to_element(edit_button).click().perform()
                logging.info("已点击编辑按钮")
                
                # 等待对话框显示
                time.sleep(2)
                return self
            except Exception as e:
                logging.warning(f"使用XPath定位编辑按钮失败: {e}")
                # 继续尝试其他方法
            
            # 方法2: 使用JavaScript查找并点击编辑按钮，使用更精确的选择器
            self.driver.execute_script(f"""
            try {{
                console.log("开始查找用户 {username} 的编辑按钮...");
                
                var rows = document.querySelectorAll('.el-table__row');
                console.log("找到表格行数量: " + rows.length);
                
                var editButton = null;
                for (var i = 0; i < rows.length; i++) {{
                    var cells = rows[i].querySelectorAll('td');
                    if (cells.length > 0) {{
                        var usernameCell = cells[0];
                        if (usernameCell.textContent.trim().includes('{username}')) {{
                            // 找到匹配的行，查找编辑按钮 - 使用更精确的选择器
                            // 查找类型为"button"，class包含"el-button--primary"和"is-link"，且内部span文本为"编辑"的按钮
                            var editSpans = rows[i].querySelectorAll('button.el-button.el-button--primary.is-link span');
                            for (var s = 0; s < editSpans.length; s++) {{
                                if (editSpans[s].textContent.trim() === '编辑') {{
                                    editButton = editSpans[s].closest('button');
                                    break;
                                }}
                            }}
                            
                            // 如果上面的选择器失败，尝试其他方式
                            if (!editButton) {{
                                // 尝试直接查找包含"编辑"文本的按钮
                                var buttons = rows[i].querySelectorAll('button');
                                for (var j = 0; j < buttons.length; j++) {{
                                    if (buttons[j].textContent.trim() === '编辑') {{
                                        editButton = buttons[j];
                                        break;
                                    }}
                                }}
                            }}
                            break;
                        }}
                    }}
                }}
                
                if (editButton) {{
                    console.log("找到编辑按钮，点击中...");
                    editButton.click();
                    console.log("已点击编辑按钮");
                }} else {{
                    // 如果仍然找不到，尝试使用更通用的方法
                    console.log("未找到编辑按钮，尝试使用更通用的方法...");
                    
                    // 查找所有包含"编辑"文本的按钮
                    var allEditButtons = document.querySelectorAll('button.el-button--primary.is-link');
                    console.log("找到所有编辑按钮数量: " + allEditButtons.length);
                    
                    // 点击第一个编辑按钮（假设只有一行数据）
                    if (allEditButtons.length > 0) {{
                        allEditButtons[0].click();
                        console.log("已点击找到的第一个编辑按钮");
                    }} else {{
                        console.log("未找到任何编辑按钮");
                    }}
                }}
            }} catch(e) {{
                console.error("点击编辑按钮时出错: " + e);
                
                // 最后的备用方法：使用XPath直接定位
                try {{
                    console.log("尝试使用XPath定位编辑按钮...");
                    var editButtonsByXPath = document.evaluate(
                        "//button[contains(@class, 'el-button--primary') and contains(@class, 'is-link') and .//span[text()='编辑']]",
                        document,
                        null,
                        XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
                        null
                    );
                    
                    if (editButtonsByXPath.snapshotLength > 0) {{
                        var button = editButtonsByXPath.snapshotItem(0);
                        button.click();
                        console.log("已使用XPath点击编辑按钮");
                    }} else {{
                        console.log("使用XPath也未找到编辑按钮");
                    }}
                }} catch(e2) {{
                    console.error("使用XPath定位编辑按钮时出错: " + e2);
                }}
            }}
            """)
            
            # 等待编辑对话框显示
            time.sleep(2)
            
            # 验证对话框标题
            try:
                dialog_title = self.wait.until(EC.presence_of_element_located(self.DIALOG_TITLE))
                if "编辑用户" in dialog_title.text:
                    logging.info("编辑用户对话框已打开")
                else:
                    logging.warning(f"对话框标题不是'编辑用户'，而是: {dialog_title.text}")
            except Exception as e:
                logging.warning(f"无法验证对话框标题: {e}")
                # 截图记录当前状态
                self.take_screenshot("edit_user_dialog_opened")
            
        except Exception as e:
            logging.error(f"点击编辑按钮失败: {e}")
            self.take_screenshot("click_edit_button_failed")
            
            # 方法3: 尝试使用Selenium的方法直接定位和点击
            try:
                logging.info("尝试使用Selenium直接定位编辑按钮")
                # 使用XPath定位包含"编辑"文本的按钮
                edit_button = self.driver.find_element(By.XPATH, "//button[contains(@class, 'el-button--primary') and contains(@class, 'is-link')]//span[text()='编辑']/parent::button")
                edit_button.click()
                logging.info("已使用Selenium点击编辑按钮")
                time.sleep(2)
            except Exception as e2:
                logging.error(f"使用Selenium定位编辑按钮也失败: {e2}")
                
                # 方法4: 最后的备用方法，使用data-v属性
                try:
                    logging.info("尝试使用data-v属性定位编辑按钮")
                    # 使用data-v属性定位按钮
                    edit_button = self.driver.find_element(By.CSS_SELECTOR, "button[data-v-6ff8da08].el-button--primary.is-link")
                    edit_button.click()
                    logging.info("已使用data-v属性点击编辑按钮")
                    time.sleep(2)
                except Exception as e3:
                    logging.error(f"使用data-v属性定位编辑按钮也失败: {e3}")
                    raise
        
        return self
    
    def edit_user_form(self, name=None, email=None, phone=None, sex=None, role_code=None):
        """
        编辑用户表单
        
        Args:
            name: 姓名，可选
            email: 邮箱，可选
            phone: 手机号，可选
            sex: 性别，可选
            role_code: 角色代码，可选
        """
        logging.info(f"编辑用户表单: 姓名={name}, 邮箱={email}, 手机号={phone}, 性别={sex}")
        
        try:
            # 编辑姓名
            if name is not None:
                self._fill_input_field(self.NAME_FORM_INPUT, name, "姓名")
            
            # 编辑邮箱
            if email is not None:
                self._fill_input_field(self.EMAIL_FORM_INPUT, email, "邮箱")
            
            # 编辑手机号
            if phone is not None:
                self._fill_input_field(self.PHONE_FORM_INPUT, phone, "手机号")
            
            # 编辑性别
            if sex is not None:
                self._fill_input_field(self.SEX_FORM_INPUT, sex, "性别")
            
            # 选择角色（如果提供）
            if role_code is not None:
                self.select_role_in_form()
            
            logging.info("用户表单编辑完成")
        except Exception as e:
            logging.error(f"编辑用户表单失败: {e}")
            # 截图记录当前状态
            self.take_screenshot("edit_user_form_failed")
            
            # 尝试使用JavaScript编辑表单
            self._edit_user_form_with_js(name, email, phone, sex)
        
        return self
    
    def _edit_user_form_with_js(self, name=None, email=None, phone=None, sex=None):
        """
        使用JavaScript编辑用户表单
        
        Args:
            name: 姓名，可选
            email: 邮箱，可选
            phone: 手机号，可选
            sex: 性别，可选
        """
        logging.info("使用JavaScript编辑用户表单")
        
        # 截图记录表单初始状态
        self.take_screenshot("before_edit_form")
        
        # 使用JavaScript填写表单
        self.driver.execute_script(f"""
        try {{
            console.log("使用JavaScript编辑用户表单...");
            
            // 确认在对话框中
            var dialog = document.querySelector('.el-dialog');
            if (!dialog) {{
                throw new Error("未找到对话框");
            }}
            
            // 编辑姓名
            if ("{name}" !== "None") {{
                var nameInput = dialog.querySelector('#name');
                if (nameInput) {{
                    nameInput.value = "{name}";
                    nameInput.dispatchEvent(new Event('input', {{ bubbles: true }}));
                    console.log("已编辑姓名: " + nameInput.value);
                }} else {{
                    console.log("未找到姓名输入框");
                }}
            }}
            
            // 编辑邮箱
            if ("{email}" !== "None") {{
                var emailInput = dialog.querySelector('.el-form-item[prop="email"] input');
                if (emailInput) {{
                    emailInput.value = "{email}";
                    emailInput.dispatchEvent(new Event('input', {{ bubbles: true }}));
                    console.log("已编辑邮箱: " + emailInput.value);
                }} else {{
                    console.log("未找到邮箱输入框");
                }}
            }}
            
            // 编辑手机号
            if ("{phone}" !== "None") {{
                var phoneInput = dialog.querySelector('.el-form-item[prop="phone"] input');
                if (phoneInput) {{
                    phoneInput.value = "{phone}";
                    phoneInput.dispatchEvent(new Event('input', {{ bubbles: true }}));
                    console.log("已编辑手机号: " + phoneInput.value);
                }} else {{
                    console.log("未找到手机号输入框");
                }}
            }}
            
            // 编辑性别
            if ("{sex}" !== "None") {{
                var sexInput = dialog.querySelector('.el-form-item[prop="sex"] input');
                if (sexInput) {{
                    sexInput.value = "{sex}";
                    sexInput.dispatchEvent(new Event('input', {{ bubbles: true }}));
                    console.log("已编辑性别: " + sexInput.value);
                }} else {{
                    console.log("未找到性别输入框");
                }}
            }}
        }} catch(e) {{
            console.error("使用JavaScript编辑表单失败: " + e);
        }}
        """)
        
        # 截图记录表单编辑后的状态
        self.take_screenshot("after_edit_form")
        
        logging.info("已使用JavaScript编辑用户表单")
        return self
    
    def edit_user(self, username, name=None, email=None, phone=None, sex=None, role_code=None):
        """
        编辑用户
        
        Args:
            username: 要编辑的用户名
            name: 新的姓名，可选
            email: 新的邮箱，可选
            phone: 新的手机号，可选
            sex: 新的性别，可选
            role_code: 新的角色代码，可选
        """
        logging.info(f"编辑用户 {username}: 姓名={name}, 邮箱={email}, 手机号={phone}, 性别={sex}")
        
        try:
            # 点击编辑按钮
            self.click_edit_button_for_user(username)
            
            # 等待对话框显示
            time.sleep(2)
            
            # 编辑表单
            self.edit_user_form(name, email, phone, sex, role_code)
            
            # 等待编辑完成
            time.sleep(1)
            
            # 截图记录提交前状态
            self.take_screenshot("before_submit_edit")
            
            # 提交表单
            self.submit_user_form()
            
            # 等待表格刷新
            time.sleep(3)
            
            # 验证用户是否编辑成功 - 如果提供了姓名，则验证姓名
            if name:
                if self.is_user_in_results(username, name):
                    logging.info(f"用户 {username} 编辑成功，新姓名: {name}")
                else:
                    logging.warning(f"未在表格中找到编辑后的用户 {username}, {name}")
            
        except Exception as e:
            logging.error(f"编辑用户失败: {e}")
            # 截图记录失败状态
            self.take_screenshot("edit_user_failed")
            raise
        
        return self
    
    def get_user_email_from_results(self, username):
        """
        从搜索结果中获取用户的邮箱
        
        Args:
            username: 用户名
            
        Returns:
            str: 用户的邮箱
        """
        logging.info(f"获取用户 {username} 的邮箱")
        
        try:
            # 使用JavaScript获取用户邮箱
            email = self.driver.execute_script(f"""
            try {{
                var rows = document.querySelectorAll('.el-table__row');
                var email = '';
                
                for (var i = 0; i < rows.length; i++) {{
                    var cells = rows[i].querySelectorAll('td');
                    if (cells.length > 0) {{
                        var usernameCell = cells[0];
                        if (usernameCell.textContent.trim().includes('{username}')) {{
                            // 邮箱通常在第三列（索引2）
                            var emailCell = cells[2];
                            if (emailCell) {{
                                email = emailCell.textContent.trim();
                                console.log("找到用户 {username} 的邮箱: " + email);
                            }}
                            break;
                        }}
                    }}
                }}
                
                return email;
            }} catch(e) {{
                console.error("获取用户邮箱时出错: " + e);
                return '';
            }}
            """)
            
            logging.info(f"用户 {username} 的邮箱为: {email}")
            return email
        except Exception as e:
            logging.error(f"获取用户邮箱失败: {e}")
            self.take_screenshot("get_user_email_failed")
            return ""
    
    def get_user_phone_from_results(self, username):
        """
        从搜索结果中获取用户的手机号
        
        Args:
            username: 用户名
            
        Returns:
            str: 用户的手机号
        """
        logging.info(f"获取用户 {username} 的手机号")
        
        try:
            # 使用JavaScript获取用户手机号
            phone = self.driver.execute_script(f"""
            try {{
                var rows = document.querySelectorAll('.el-table__row');
                var phone = '';
                
                for (var i = 0; i < rows.length; i++) {{
                    var cells = rows[i].querySelectorAll('td');
                    if (cells.length > 0) {{
                        var usernameCell = cells[0];
                        if (usernameCell.textContent.trim().includes('{username}')) {{
                            // 手机号通常在第四列（索引3）
                            var phoneCell = cells[3];
                            if (phoneCell) {{
                                phone = phoneCell.textContent.trim();
                                console.log("找到用户 {username} 的手机号: " + phone);
                            }}
                            break;
                        }}
                    }}
                }}
                
                return phone;
            }} catch(e) {{
                console.error("获取用户手机号时出错: " + e);
                return '';
            }}
            """)
            
            logging.info(f"用户 {username} 的手机号为: {phone}")
            return phone
        except Exception as e:
            logging.error(f"获取用户手机号失败: {e}")
            self.take_screenshot("get_user_phone_failed")
            return ""
    
    def edit_user_sex(self, username):
        """
        编辑用户性别（切换性别）
        
        Args:
            username: 要编辑的用户名
            
        Returns:
            self
        """
        logging.info(f"编辑用户 {username} 的性别")
        
        try:
            # 先点击编辑按钮
            self.click_edit_button_for_user(username)
            
            # 等待对话框显示
            time.sleep(2)
            
            # 使用JavaScript点击性别选择器并选择一个不同的值
            self.driver.execute_script("""
            try {
                // 点击性别选择器
                var sexSelector = document.querySelector('.el-dialog .el-form-item[prop="sex"] .el-select');
                if (sexSelector) {
                    sexSelector.click();
                    console.log("已点击性别选择器");
                }
            } catch(e) {
                console.error("点击性别选择器时出错: " + e);
            }
            """)
            
            # 等待下拉菜单显示
            time.sleep(2)
            
            # 选择一个不同的性别
            self.driver.execute_script("""
            try {
                // 获取当前选中的性别
                var currentSex = document.querySelector('.el-select-dropdown__item.selected');
                var currentSexText = currentSex ? currentSex.textContent.trim() : '';
                console.log("当前选中的性别: " + currentSexText);
                
                // 选择一个不同的性别
                var sexOptions = document.querySelectorAll('.el-select-dropdown__item');
                var clicked = false;
                
                for (var i = 0; i < sexOptions.length; i++) {
                    var optionText = sexOptions[i].textContent.trim();
                    if (optionText !== currentSexText) {
                        sexOptions[i].click();
                        console.log("已选择新的性别: " + optionText);
                        clicked = true;
                        break;
                    }
                }
                
                if (!clicked && sexOptions.length > 0) {
                    // 如果没有点击任何选项（可能只有一个选项），点击第一个
                    sexOptions[0].click();
                    console.log("已选择第一个性别选项: " + sexOptions[0].textContent.trim());
                }
            } catch(e) {
                console.error("选择性别时出错: " + e);
            }
            """)
            
            # 等待选择完成
            time.sleep(2)
            
            # 点击确定按钮
            self.click_dialog_submit_button()
            
            # 等待操作完成
            time.sleep(2)
            
            return self
        except Exception as e:
            logging.error(f"编辑用户性别失败: {e}")
            self.take_screenshot("edit_user_sex_failed")
            raise 